home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Plotting / aa_Intel_Only / Gnuplot / Unused / gplt_x11.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  29.2 KB  |  955 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: gplt_x11.c%v 3.38.2.118 1993/04/19 23:35:13 woo Exp woo $";
  3. #endif
  4.  
  5.  
  6. /*-----------------------------------------------------------------------------
  7.  *   gnuplot_x11 - X11 outboard terminal driver for gnuplot 3.3
  8.  *
  9.  *   Requires installation of companion inboard x11 driver in gnuplot/term.c
  10.  *
  11.  *   Acknowledgements: 
  12.  *      Chris Peterson (MIT)
  13.  *      Dana Chee (Bellcore) 
  14.  *      Arthur Smith (Cornell)
  15.  *      Hendri Hondorp (University of Twente, The Netherlands)
  16.  *      Bill Kucharski (Solbourne)
  17.  *      Charlie Kline (University of Illinois)
  18.  *      Yehavi Bourvine (Hebrew University of Jerusalem, Israel)
  19.  *      Russell Lang (Monash University, Australia)
  20.  *      O'Reilly & Associates: X Window System - Volumes 1 & 2
  21.  *
  22.  *   This code is provided as is and with no warranties of any kind.
  23.  *       
  24.  *---------------------------------------------------------------------------*/
  25.  
  26. #define DEFAULT_X11
  27. #if defined(VMS) || defined(CRIPPLED_SELECT)
  28. #undef DEFAULT_X11
  29. #endif
  30. #if defined(VMS) && defined(CRIPPLED_SELECT)
  31. Error. Incompatible options.
  32. #endif
  33.  
  34. #include <X11/Xos.h>
  35. #include <X11/Xlib.h>
  36. #include <X11/Xutil.h>
  37. #include <X11/Xatom.h>
  38. #include <X11/Xresource.h>
  39.  
  40. #include <stdio.h>
  41. #include <signal.h>
  42.  
  43. #ifdef BSD_TYPES
  44. #include <sys/bsdtypes.h>
  45. #endif /* BSD_TYPES */
  46.  
  47. #ifdef OLD_SELECT
  48. #define FD_SET(n, p)    ((p)->fds_bits[0] |= (1 << ((n) % 32)))
  49. #define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1 << ((n) % 32)))
  50. #define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1 << ((n) % 32)))
  51. #define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
  52. #endif /* OLD_SELECT */
  53.  
  54. #if !defined(VMS) && !defined(FD_SET)
  55. #include <sys/select.h>
  56. #endif /* !VMS && !FD_SET */
  57.  
  58. #ifdef SOLARIS
  59. #include <sys/systeminfo.h>
  60. #endif /* SOLARIS */
  61.  
  62.  
  63. #include <errno.h>
  64. extern int errno;
  65.  
  66. #define FallbackFont "fixed"
  67.  
  68. #define Ncolors 13
  69. unsigned long colors[Ncolors];
  70.  
  71. #define Nwidths 10
  72. unsigned int widths[Nwidths] = { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  73.  
  74. #define Ndashes 10
  75. char dashes[Ndashes][5];
  76.  
  77. Display *dpy; int scr; Window win, root;
  78. Visual *vis; GC gc = (GC)0; Pixmap pixmap; XFontStruct *font;
  79. unsigned int W = 640, H = 450; int D, gX = 100, gY = 100;
  80. unsigned int BorderWidth = 2;
  81. unsigned User_Size = 0, User_Position = 0; /* User specified? */
  82.  
  83.  
  84. Bool Mono = 0, Gray = 0, Rv = 0, Clear = 0;
  85. char Name[64] = "gnuplot";
  86. char Class[64] = "Gnuplot";
  87.  
  88. int cx=0, cy=0, vchar, nc = 0, ncalloc = 0;
  89. double xscale, yscale, pointsize;
  90. #define X(x) (int) (x * xscale)
  91. #define Y(y) (int) ((4095-y) * yscale)
  92. enum JUSTIFY { LEFT, CENTRE, RIGHT } jmode;
  93.  
  94. #define Nbuf 1024
  95. char buf[Nbuf], **commands = (char **)0;
  96.  
  97. FILE *X11_ipc;
  98. char X11_ipcpath[32];
  99.  
  100. #ifdef OW_BOTCH
  101. static void dummy() { XtInitialize; }
  102. #endif
  103.  
  104.  
  105. /*-----------------------------------------------------------------------------
  106.  *   main program 
  107.  *---------------------------------------------------------------------------*/
  108.  
  109. main(argc, argv) int argc; char *argv[]; {
  110.  
  111.    preset(argc, argv);
  112.    mainloop();
  113.    exit(0);
  114.  
  115.    }
  116.  
  117. /*-----------------------------------------------------------------------------
  118.  *   mainloop processing - process X events and input from gnuplot
  119.  *
  120.  *   Three different versions of main loop processing are provided to support
  121.  *   three different platforms.
  122.  * 
  123.  *   DEFAULT_X11:     use select() for both X events and input on stdin 
  124.  *                    from gnuplot inboard driver
  125.  *
  126.  *   CRIPPLED_SELECT: use select() to service X events and check during 
  127.  *                    select timeout for temporary plot file created
  128.  *                    by inboard driver
  129.  *
  130.  *   VMS:             use XNextEvent to service X events and AST to
  131.  *                    service input from gnuplot inboard driver on stdin 
  132.  *---------------------------------------------------------------------------*/
  133.  
  134.  
  135. #ifdef DEFAULT_X11
  136. /*-----------------------------------------------------------------------------
  137.  *    DEFAULT_X11 mainloop
  138.  *---------------------------------------------------------------------------*/
  139.  
  140. mainloop() {
  141.    int nf, nfds, cn = ConnectionNumber(dpy), in = fileno(stdin);
  142.    struct timeval timeout, *timer = (struct timeval *)0;
  143.    fd_set rset, tset;
  144.    unsigned long all = 0xffffffff;
  145.    XEvent xe;
  146.  
  147.    X11_ipc = stdin;
  148.  
  149.    FD_ZERO(&rset);
  150.    FD_SET(cn, &rset);
  151.  
  152.    FD_SET(in, &rset);
  153.    nfds = (cn > in) ? cn + 1 : in + 1;
  154.  
  155. #ifdef ISC22
  156. /* Added by Robert Eckardt, RobertE@beta.TP2.Ruhr-Uni-Bochum.de */
  157.    timeout.tv_sec  = 0;        /* select() in ISC2.2 needs timeout */
  158.    timeout.tv_usec = 300000;    /* otherwise input from gnuplot is */
  159.    timer = &timeout;        /* suspended til next X event. */
  160. #endif /* ISC22      (0.3s are short enough not to be noticed */
  161.  
  162.    while(1) {
  163.       tset = rset;
  164.       nf = select(nfds, &tset, (fd_set *)0, (fd_set *)0, timer);
  165.       if (nf < 0) {
  166.      if (errno == EINTR) continue;
  167.      fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
  168.      exit(1);
  169.      }
  170.       nf > 0 && XNoOp(dpy);
  171.       if (FD_ISSET(cn, &tset)) {
  172.      while (XCheckMaskEvent(dpy, all, &xe)) {
  173.         (xe.type == ConfigureNotify)  && resize(&xe); 
  174.         }
  175.      }
  176.       FD_ISSET(in, &tset) && record();
  177.       }
  178.    }
  179.  
  180. #endif
  181.  
  182.  
  183. #ifdef CRIPPLED_SELECT
  184. /*-----------------------------------------------------------------------------
  185.  *    CRIPPLED_SELECT mainloop
  186.  *---------------------------------------------------------------------------*/
  187.  
  188. mainloop() {
  189.    int nf, nfds, cn = ConnectionNumber(dpy);
  190.    struct timeval timeout, *timer;
  191.    fd_set rset, tset;
  192.    unsigned long all = 0xffffffff;
  193.    XEvent xe;
  194.  
  195.    FD_ZERO(&rset);
  196.    FD_SET(cn, &rset);
  197.  
  198.    timeout.tv_sec = 1;
  199.    timeout.tv_usec = 0;
  200.    timer = &timeout;
  201.    sprintf(X11_ipcpath, "/tmp/Gnuplot_%d", getppid());
  202.    nfds = cn + 1;
  203.  
  204.    while(1) {
  205.       tset = rset;
  206.       nf = select(nfds, &tset, (fd_set *)0, (fd_set *)0, timer);
  207.       if (nf < 0) {
  208.      if (errno == EINTR) continue;
  209.      fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
  210.      exit(1);
  211.      }
  212.       nf > 0 && XNoOp(dpy);
  213.       if (FD_ISSET(cn, &tset)) {
  214.      while (XCheckMaskEvent(dpy, all, &xe)) {
  215.         (xe.type == ConfigureNotify)  && resize(&xe); 
  216.         }
  217.      }
  218.       if ((X11_ipc = fopen(X11_ipcpath, "r"))) {
  219.      unlink(X11_ipcpath);
  220.      record();
  221.      fclose(X11_ipc);
  222.      }
  223.       }
  224.    }
  225. #endif /* CRIPPLED_SELECT */
  226.  
  227.  
  228. #ifdef VMS
  229. /*-----------------------------------------------------------------------------
  230.  *    VMS mainloop - Yehavi Bourvine - YEHAVI@VMS.HUJI.AC.IL
  231.  *---------------------------------------------------------------------------*/
  232.  
  233. /*  In VMS there is no decent Select(). hence, we have to loop inside
  234.  *  XGetNextEvent for getting the next X window event. In order to get input
  235.  *  from the master we assign a channel to SYS$INPUT and use AST's in order to
  236.  *  receive data. */
  237.  
  238. #include <iodef.h>
  239. char    STDIIN[] = "SYS$INPUT:";
  240. short   STDIINchannel, STDIINiosb[4];
  241. struct  { short size, type; char  *address; } STDIINdesc;
  242. char    STDIINbuffer[64];
  243. int     status;
  244.  
  245.  
  246. mainloop() {
  247.    XEvent xe;
  248.  
  249.    STDIINdesc.size = strlen(STDIIN); 
  250.    STDIINdesc.type = 0;
  251.    STDIINdesc.address = STDIIN;
  252.    status = sys$assign(&STDIINdesc, &STDIINchannel, 0, 0, 0);
  253.    if((status & 0x1) == 0)  exit(status); 
  254.    ast();
  255.  
  256.    for(;;) {
  257.       XNextEvent(dpy, &xe);
  258.       (xe.type == ConfigureNotify)  && resize(&xe); 
  259.       }
  260.    }
  261.  
  262. ast() {
  263.    int record();
  264.    int status = sys$qio(0, STDIINchannel, IO$_READVBLK, STDIINiosb, record,
  265.                 0, STDIINbuffer, sizeof(STDIINbuffer) -1,0, 0, 0, 0);
  266.    if((status & 0x1) == 0) exit(status);
  267.    }
  268. #endif /* VMS */
  269.  
  270.  
  271. #ifndef VMS
  272. /*-----------------------------------------------------------------------------
  273.  *   record - record new plot from gnuplot inboard X11 driver (Unix)
  274.  *---------------------------------------------------------------------------*/
  275.  
  276. record() {
  277.  
  278.    while (fgets(buf, Nbuf, X11_ipc)) {
  279.      if (*buf == 'G') {                           /* enter graphics mode */
  280.      if (commands) {
  281.         int n; for (n=0; n<nc; n++) free(commands[n]);
  282.         free(commands);
  283.         }
  284.      commands = (char **)0; nc = ncalloc = 0;
  285.          }
  286.       else if (*buf == 'E') { display(); break; } /* leave graphics mode */
  287.       else if (*buf == 'R') { exit(0); }          /* leave X11/x11 mode  */
  288.       else {                                      /* record command      */
  289.      char *p;
  290.      if (nc >= ncalloc) {
  291.         ncalloc = ncalloc*2 + 1;
  292.         commands = (commands)
  293.            ? (char **)realloc(commands, ncalloc * sizeof(char *))
  294.            : (char **)malloc(sizeof(char *));
  295.         }
  296.      p = (char *)malloc((unsigned)strlen(buf)+1);
  297.      if (!commands || !p) {
  298.         fprintf(stderr, "gnuplot: can't get memory. X11 aborted.\n");
  299.         exit(1);
  300.         }
  301.      commands[nc++] = strcpy(p, buf);
  302.      }
  303.       }
  304.    if (feof(X11_ipc) || ferror(X11_ipc)) exit(1);
  305.    }
  306.  
  307. #else    /* VMS */
  308. /*-----------------------------------------------------------------------------
  309.  *   record - record new plot from gnuplot inboard X11 driver (VMS)
  310.  *---------------------------------------------------------------------------*/
  311.  
  312. record() {
  313.    int    status;
  314.  
  315.    if((STDIINiosb[0] & 0x1) == 0) exit(STDIINiosb[0]);
  316.    STDIINbuffer[STDIINiosb[1]] = '\0';
  317.    strcpy(buf, STDIINbuffer);
  318.  
  319.    if (*buf == 'G') {                           /* enter graphics mode */
  320.       if (commands) {
  321.          int n; for (n=0; n<nc; n++) free(commands[n]);
  322.          free(commands);
  323.          }
  324.        commands = (char **)0; nc = ncalloc = 0;
  325.        }
  326.    else if (*buf == 'E') {                      /* leave graphics mode */
  327.       display(); 
  328.       }
  329.    else if (*buf == 'R') {                      /* leave x11/X11 mode  */
  330.        sys$cancel(STDIINchannel);
  331.        XCloseDisplay(dpy);
  332.        sys$delprc(0,0);      /* Somehow it doesn't drop itself... */
  333.        exit(1); 
  334.        }
  335.    else {                                       /* record command      */
  336.       char *p;
  337.       if (nc >= ncalloc) {
  338.      ncalloc = ncalloc*2 + 1;
  339.      commands = (commands)
  340.         ? (char **)realloc(commands, ncalloc * sizeof(char *))
  341.         : (char **)malloc(sizeof(char *));
  342.      }
  343.       p = (char *)malloc((unsigned)strlen(buf)+1);
  344.       if (!commands || !p) {
  345.      fprintf(stderr, "gnuplot: can't get memory. X11 aborted.\n");
  346.      exit(1);
  347.      }
  348.       commands[nc++] = strcpy(p, buf);
  349.       }
  350.    ast();
  351.    }
  352. #endif /* VMS */
  353.  
  354. /*-----------------------------------------------------------------------------
  355.  *   display - display last plot from gnuplot inboard X11 driver
  356.  *---------------------------------------------------------------------------*/
  357.  
  358. display() {
  359.    int n, x, y, sw, sl, lt, width, type, point, px, py;
  360.    char *buf, *str;
  361.  
  362.    if (!nc) return;
  363.  
  364.    /* set scaling factor between internal driver & window geometry */
  365.    xscale = (double)W / 4096.;  yscale = (double)H / 4096.;  
  366.  
  367.    /* create new pixmap & GC */
  368.    if (gc) { XFreeGC(dpy, gc); XFreePixmap(dpy, pixmap); }
  369.    pixmap = XCreatePixmap(dpy, root, W, H, D);
  370.    gc = XCreateGC(dpy, pixmap, 0, (XGCValues *)0);
  371.    XSetFont(dpy, gc, font->fid);
  372.  
  373.    /* set pixmap background */
  374.    XSetForeground(dpy, gc, colors[0]);
  375.    XFillRectangle(dpy, pixmap, gc, 0, 0, W, H);
  376.    XSetBackground(dpy, gc, colors[0]);
  377.  
  378.    /* set new pixmap as window background */
  379.    XSetWindowBackgroundPixmap(dpy, win, pixmap);
  380.  
  381.    /* top the window but don't put keyboard or mouse focus into it. */
  382.    XMapRaised(dpy, win);
  383.  
  384.    /* momentarily clear the window first if requested */
  385.    if (Clear) {
  386.       XClearWindow(dpy, win);
  387.       XFlush(dpy);
  388.       }
  389.  
  390.    /* loop over accumulated commands from inboard driver */
  391.    for (n=0; n<nc; n++) {
  392.       buf = commands[n];
  393.  
  394.       /*   X11_vector(x,y) - draw vector  */
  395.       if (*buf == 'V') { 
  396.      sscanf(buf, "V%4d%4d", &x, &y);  
  397.      XDrawLine(dpy, pixmap, gc, X(cx), Y(cy), X(x), Y(y));
  398.      cx = x; cy = y;
  399.      }
  400.  
  401.       /*   X11_move(x,y) - move  */
  402.       else if (*buf == 'M') 
  403.      sscanf(buf, "M%4d%4d", &cx, &cy);  
  404.  
  405.       /*   X11_put_text(x,y,str) - draw text   */
  406.       else if (*buf == 'T') { 
  407.      sscanf(buf, "T%4d%4d", &x, &y);  
  408.      str = buf + 9; sl = strlen(str) - 1;
  409.      sw = XTextWidth(font, str, sl);
  410.      switch(jmode) {
  411.         case LEFT:   sw = 0;     break;
  412.         case CENTRE: sw = -sw/2; break;
  413.         case RIGHT:  sw = -sw;   break;
  414.         }
  415.      XSetForeground(dpy, gc, colors[2]);
  416.      XDrawString(dpy, pixmap, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
  417.      XSetForeground(dpy, gc, colors[lt+3]);
  418.      }
  419.  
  420.       /*   X11_justify_text(mode) - set text justification mode  */
  421.       else if (*buf == 'J') 
  422.      sscanf(buf, "J%4d", &jmode);
  423.  
  424.       /*   X11_linetype(type) - set line type  */
  425.       else if (*buf == 'L') { 
  426.      sscanf(buf, "L%4d", <);
  427.      lt = (lt%8)+2;
  428.      width = widths[lt];
  429.      if (dashes[lt][0]) {
  430.         type = LineOnOffDash;
  431.         XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
  432.         }
  433.      else {
  434.         type = LineSolid;
  435.         }
  436.      XSetForeground(dpy, gc, colors[lt+3]);
  437.      XSetLineAttributes( dpy,gc, width, type, CapButt, JoinBevel);
  438.        }
  439.  
  440.       /*   X11_point(number) - draw a point */
  441.       else if (*buf == 'P') { 
  442.       sscanf(buf, "P%1d%4d%4d", &point, &x, &y);  
  443.       if (point==7) {
  444.          /* set point size */
  445.          px = (int) (x * xscale * pointsize);
  446.          py = (int) (y * yscale * pointsize);
  447.          }
  448.       else {
  449.         if (type != LineSolid || width != 0) {  /* select solid line */
  450.            XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinBevel);
  451.            }
  452.         switch(point) {
  453.            case 0: /* dot */
  454.            XDrawLine(dpy,pixmap,gc, X(x), Y(y), X(x), Y(y));
  455.            break;
  456.            case 1: /* do diamond */ 
  457.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y), X(x), Y(y)-py);
  458.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-py, X(x)+px, Y(y));
  459.            XDrawLine(dpy,pixmap,gc, X(x)+px, Y(y), X(x), Y(y)+py);
  460.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)+py, X(x)-px, Y(y));
  461.            XDrawLine(dpy,pixmap,gc, X(x), Y(y), X(x), Y(y));
  462.            break;
  463.            case 2: /* do plus */ 
  464.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y), X(x)+px, Y(y));
  465.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-py, X(x), Y(y)+py);
  466.            break;
  467.            case 3: /* do box */ 
  468.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)-py, X(x)+px, Y(y)-py);
  469.            XDrawLine(dpy,pixmap,gc, X(x)+px, Y(y)-py, X(x)+px, Y(y)+py);
  470.            XDrawLine(dpy,pixmap,gc, X(x)+px, Y(y)+py, X(x)-px, Y(y)+py);
  471.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)+py, X(x)-px, Y(y)-py);
  472.            XDrawLine(dpy,pixmap,gc, X(x), Y(y), X(x), Y(y));
  473.            break;
  474.            case 4: /* do X */ 
  475.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)-py, X(x)+px, Y(y)+py);
  476.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)+py, X(x)+px, Y(y)-py);
  477.            break;
  478.            case 5: /* do triangle */ 
  479.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-(4*px/3), 
  480.                  X(x)-(4*px/3), Y(y)+(2*py/3));
  481.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-(4*px/3), 
  482.                  X(x)+(4*px/3), Y(y)+(2*py/3));
  483.            XDrawLine(dpy,pixmap,gc, X(x)-(4*px/3), Y(y)+(2*py/3), 
  484.                  X(x)+(4*px/3), Y(y)+(2*py/3));
  485.            XDrawLine(dpy,pixmap,gc, X(x), Y(y), X(x), Y(y));
  486.            break;
  487.            case 6: /* do star */ 
  488.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y), X(x)+px, Y(y));
  489.            XDrawLine(dpy,pixmap,gc, X(x), Y(y)-py, X(x), Y(y)+py);
  490.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)-py, X(x)+px, Y(y)+py);
  491.            XDrawLine(dpy,pixmap,gc, X(x)-px, Y(y)+py, X(x)+px, Y(y)-py);
  492.            break;
  493.            }
  494.         if (type != LineSolid || width != 0) {  /* select solid line */
  495.            XSetLineAttributes(dpy, gc, width, type, CapButt, JoinBevel);
  496.            }
  497.         }
  498.      }
  499.       }
  500.  
  501.    /* trigger exposure of background pixmap */
  502.    XClearWindow(dpy,win);
  503.    XFlush(dpy);
  504.    }
  505.  
  506. /*-----------------------------------------------------------------------------
  507.  *   resize - rescale last plot if window resized
  508.  *---------------------------------------------------------------------------*/
  509.  
  510. resize(xce) XConfigureEvent *xce; {
  511.    int w = xce->width, h = xce->height;
  512.    
  513.    if (w>1 && h>1 && (w != W || h != H)) {
  514.       W = w; H = h;
  515.       display();
  516.       }
  517.    }
  518.  
  519.  
  520. /*-----------------------------------------------------------------------------
  521.  *   preset - determine options, open display, create window
  522.  *---------------------------------------------------------------------------*/
  523.  
  524. #define On(v) ( !strcmp(v,"on") || !strcmp(v,"true") || \
  525.         !strcmp(v,"On") || !strcmp(v,"True") )
  526.  
  527. #define AppDefDir "/usr/lib/X11/app-defaults"
  528. #ifndef MAXHOSTNAMELEN
  529. #define MAXHOSTNAMELEN 64
  530. #endif
  531.  
  532. static XrmDatabase dbCmd, dbApp, dbDef, dbEnv, db = (XrmDatabase)0;
  533.  
  534. char *pr_GetR(), *getenv(), *type[20];
  535. XrmValue value;
  536.  
  537. #define Nopt 27
  538. static XrmOptionDescRec options[] = {
  539.    {"-mono",             ".mono",             XrmoptionNoArg,   "on" },
  540.    {"-gray",             ".gray",             XrmoptionNoArg,   "on" },
  541.    {"-clear",            ".clear",            XrmoptionNoArg,   "on" },
  542.    {"-tvtwm",            ".tvtwm",            XrmoptionNoArg,   "on" },
  543.    {"-pointsize",        ".pointsize",        XrmoptionSepArg,  NULL },
  544.    {"-display",          ".display",          XrmoptionSepArg,  NULL },
  545.    {"-name",             ".name",             XrmoptionSepArg,  NULL },
  546.    {"-geometry",         "*geometry",         XrmoptionSepArg,  NULL },
  547.    {"-background",       "*background",       XrmoptionSepArg,  NULL },
  548.    {"-bg",               "*background",       XrmoptionSepArg,  NULL },
  549.    {"-foreground",       "*foreground",       XrmoptionSepArg,  NULL },
  550.    {"-fg",               "*foreground",       XrmoptionSepArg,  NULL },
  551.    {"-bordercolor",      "*bordercolor",      XrmoptionSepArg,  NULL },
  552.    {"-bd",               "*bordercolor",      XrmoptionSepArg,  NULL },
  553.    {"-borderwidth",      ".borderwidth",      XrmoptionSepArg,  NULL },
  554.    {"-bw",               ".borderwidth",      XrmoptionSepArg,  NULL },
  555.    {"-font",             "*font",             XrmoptionSepArg,  NULL },
  556.    {"-fn",               "*font",             XrmoptionSepArg,  NULL },
  557.    {"-reverse",          "*reverseVideo",     XrmoptionNoArg,   "on" },
  558.    {"-rv",               "*reverseVideo",     XrmoptionNoArg,   "on" },
  559.    {"+rv",               "*reverseVideo",     XrmoptionNoArg,   "off"},
  560.    {"-iconic",           "*iconic",           XrmoptionNoArg,   "on" },
  561.    {"-synchronous",      "*synchronous",      XrmoptionNoArg,   "on" },
  562.    {"-xnllanguage",      "*xnllanguage",      XrmoptionSepArg,  NULL },
  563.    {"-selectionTimeout", "*selectionTimeout", XrmoptionSepArg,  NULL },
  564.    {"-title",            ".title",            XrmoptionSepArg,  NULL },
  565.    {"-xrm",              NULL,                XrmoptionResArg,  NULL },
  566.    };
  567.  
  568. preset(argc, argv) int argc; char *argv[]; {
  569.    int Argc = argc; char **Argv = argv;
  570.  
  571.    char *display = getenv("DISPLAY"),  *home = getenv("HOME");
  572.    char *server_defaults, *env, buf[256];
  573.  
  574.    /*---set to ignore ^C and ^Z----------------------------------------------*/
  575.  
  576.    signal(SIGINT, SIG_IGN);
  577. #ifdef SIGTSTP
  578.    signal(SIGTSTP, SIG_IGN);
  579. #endif
  580.  
  581.    /*---prescan arguments for "-name"----------------------------------------*/
  582.  
  583.    while(++Argv, --Argc > 0) {
  584.       if (!strcmp(*Argv, "-name") && Argc > 1) {
  585.      strncpy(Name, Argv[1], 64);
  586.      strncpy(Class, Argv[1], 64);
  587.      if (Class[0] >= 'a' && Class[0] <= 'z') Class[0] -= 0x20;
  588.      }
  589.       }
  590.    Argc = argc; Argv = argv;
  591.  
  592.    /*---parse command line---------------------------------------------------*/
  593.  
  594.    XrmInitialize();
  595.    XrmParseCommand(&dbCmd, options, Nopt, Name, &Argc, Argv);
  596.    if (Argc > 1) {
  597.       fprintf(stderr, "\ngnuplot: bad option: %s\n", Argv[1]);
  598.       fprintf(stderr, "gnuplot: X11 aborted.\n");
  599.       exit(1);
  600.       }
  601.    if (pr_GetR(dbCmd, ".display")) display = value.addr;
  602.  
  603.    /*---open display---------------------------------------------------------*/
  604.  
  605.    dpy = XOpenDisplay(display); 
  606.    if (!dpy) {
  607.       fprintf(stderr, "\ngnuplot: unable to open display '%s'\n", display);
  608.       fprintf(stderr, "gnuplot: X11 aborted.\n");
  609.       exit(1);
  610.       }
  611.    scr = DefaultScreen(dpy);
  612.    vis = DefaultVisual(dpy,scr);
  613.    D = DefaultDepth(dpy,scr);
  614.    root = DefaultRootWindow(dpy);
  615.    server_defaults = XResourceManagerString(dpy);
  616.  
  617.    /*---get application defaults--(subset of Xt processing)------------------*/
  618.  
  619.    sprintf(buf, "%s/%s", AppDefDir, "Gnuplot");
  620.    dbApp = XrmGetFileDatabase(buf);
  621.    XrmMergeDatabases(dbApp, &db);
  622.  
  623.    /*---get server or ~/.Xdefaults-------------------------------------------*/
  624.  
  625.    if (server_defaults)
  626.       dbDef = XrmGetStringDatabase(server_defaults);
  627.    else {
  628.       sprintf(buf, "%s/.Xdefaults", home);
  629.       dbDef = XrmGetFileDatabase(buf);
  630.       }
  631.    XrmMergeDatabases(dbDef, &db);
  632.  
  633.    /*---get XENVIRONMENT or  ~/.Xdefaults-hostname---------------------------*/
  634.  
  635. #ifndef VMS
  636.    if (env = getenv("XENVIRONMENT")) 
  637.       dbEnv = XrmGetFileDatabase(env);
  638.    else {
  639.       char *p, host[MAXHOSTNAMELEN];
  640. #ifdef SOLARIS
  641.       if (sysinfo(SI_HOSTNAME, host, MAXHOSTNAMELEN) < 0) {
  642.          fprintf(stderr, "gnuplot: sysinfo failed. X11 aborted.\n");
  643. #else
  644.       if (gethostname(host, MAXHOSTNAMELEN) < 0) {
  645.          fprintf(stderr, "gnuplot: gethostname failed. X11 aborted.\n");
  646. #endif /* SOLARIS */
  647.      exit(1);
  648.      }
  649.       if (p = index(host, '.')) *p = '\0';
  650.       sprintf(buf, "%s/.Xdefaults-%s", home, host);
  651.       dbEnv = XrmGetFileDatabase(buf);
  652.       }
  653.    XrmMergeDatabases(dbEnv, &db);
  654. #endif   /* not VMS */
  655.  
  656.    /*---merge command line options-------------------------------------------*/
  657.  
  658.    XrmMergeDatabases(dbCmd, &db);
  659.  
  660.    /*---set geometry, font, colors, line widths, dash styles, point size-----*/
  661.  
  662.    pr_geometry();
  663.    pr_font();
  664.    pr_color();
  665.    pr_width();
  666.    pr_dashes();
  667.    pr_pointsize();
  668.  
  669.    /*---create window--------------------------------------------------------*/
  670.  
  671.    pr_window();
  672.  
  673.    } 
  674.  
  675. /*-----------------------------------------------------------------------------
  676.  *   pr_GetR - get resource from database using "-name" option (if any)
  677.  *---------------------------------------------------------------------------*/
  678.  
  679. char *
  680. pr_GetR(db, resource) XrmDatabase db; char *resource; {
  681.    char name[128], class[128], *rc;
  682.  
  683.    strcpy(name, Name); strcat(name, resource);
  684.    strcpy(class, Class); strcat(class, resource);
  685.    rc = XrmGetResource(db, name, class, type, &value)
  686.       ? (char *)value.addr 
  687.       : (char *)0;
  688.    return(rc);
  689.    }
  690.  
  691. /*-----------------------------------------------------------------------------
  692.  *   pr_color - determine color values
  693.  *---------------------------------------------------------------------------*/
  694.  
  695. char color_keys[Ncolors][30] =   { 
  696.    "background", "bordercolor", "text", "border", "axis", 
  697.    "line1", "line2", "line3",  "line4", 
  698.    "line5", "line6", "line7",  "line8" 
  699.    };
  700. char color_values[Ncolors][30] = { 
  701.    "white", "black",  "black",  "black",  "black", 
  702.    "red",   "green",  "blue",   "magenta", 
  703.    "cyan",  "sienna", "orange", "coral" 
  704.    };
  705. char gray_values[Ncolors][30] = { 
  706.    "black",   "white",  "white",  "gray50", "gray50",
  707.    "gray100", "gray60", "gray80", "gray40", 
  708.    "gray90",  "gray50", "gray70", "gray30" 
  709.    };
  710.  
  711. pr_color() {
  712.    unsigned long black = BlackPixel(dpy, scr), white = WhitePixel(dpy,scr);
  713.    char option[20], color[30], *v, *type; 
  714.    XColor xcolor;
  715.    Colormap cmap;
  716.    double intensity = -1;
  717.    int n;
  718.  
  719.    pr_GetR(db, ".mono")         && On(value.addr) && Mono++;
  720.    pr_GetR(db, ".gray")         && On(value.addr) && Gray++;
  721.    pr_GetR(db, ".reverseVideo") && On(value.addr) && Rv++;
  722.  
  723.    if (!Gray && (vis->class == GrayScale || vis->class == StaticGray)) Mono++;
  724.  
  725.    if (!Mono) {
  726.       cmap = DefaultColormap(dpy, scr);
  727.       type = (Gray) ? "Gray" : "Color";
  728.  
  729.       for (n=0; n<Ncolors; n++) {
  730.      strcpy(option, ".");
  731.      strcat(option, color_keys[n]);
  732.      (n > 1) && strcat(option, type);
  733.      v = pr_GetR(db, option) 
  734.          ? value.addr
  735.          : ((Gray) ? gray_values[n] : color_values[n]);
  736.  
  737.      if (sscanf(v,"%30[^,],%lf", color, &intensity) == 2) {
  738.         if (intensity < 0 || intensity > 1) {
  739.            fprintf(stderr, "\ngnuplot: invalid color intensity in '%s'\n",
  740.                        color);
  741.            intensity = 1;
  742.            }
  743.         }
  744.      else { 
  745.         strcpy(color, v);
  746.         intensity = 1;
  747.         }
  748.  
  749.      if (!XParseColor(dpy, cmap, color, &xcolor)) {
  750.         fprintf(stderr, "\ngnuplot: unable to parse '%s'. Using black.\n",
  751.                     color);
  752.         colors[n] = black;
  753.         }
  754.      else {
  755.         xcolor.red *= intensity;
  756.         xcolor.green *= intensity;
  757.         xcolor.blue *= intensity;
  758.         if (XAllocColor(dpy, cmap, &xcolor)) {
  759.            colors[n] = xcolor.pixel;
  760.            }
  761.         else {
  762.            fprintf(stderr, "\ngnuplot: can't allocate '%s'. Using black.\n",
  763.                         v);
  764.            colors[n] = black;
  765.            }
  766.         }
  767.      }
  768.       }
  769.    else {
  770.       colors[0] = (Rv) ? black : white ;
  771.       for (n=1; n<Ncolors; n++)  colors[n] = (Rv) ? white : black;
  772.       }
  773.    }
  774.  
  775. /*-----------------------------------------------------------------------------
  776.  *   pr_dashes - determine line dash styles 
  777.  *---------------------------------------------------------------------------*/
  778.  
  779. char dash_keys[Ndashes][10] =   { 
  780.    "border", "axis",
  781.    "line1", "line2", "line3",  "line4", "line5", "line6", "line7",  "line8" 
  782.    };
  783.  
  784. char dash_mono[Ndashes][10] =   { 
  785.    "0", "16",
  786.    "0", "42", "13",  "44", "15", "4441", "42",  "13" 
  787.    };
  788.  
  789. char dash_color[Ndashes][10] =   { 
  790.    "0", "16",
  791.    "0", "0", "0", "0", "0", "0", "0", "0" 
  792.    };
  793.  
  794. pr_dashes() {
  795.    int n, j, l, ok;
  796.    char option[20], *v; 
  797.    for (n=0; n<Ndashes; n++) {
  798.       strcpy(option, ".");
  799.       strcat(option, dash_keys[n]);
  800.       strcat(option, "Dashes");
  801.       v = pr_GetR(db, option) 
  802.       ? value.addr
  803.       : ((Mono) ? dash_mono[n] : dash_color[n]);
  804.       l = strlen(v);
  805.       if (l == 1 && *v == '0') {
  806.      dashes[n][0] = (unsigned char)0;
  807.      continue;
  808.      }
  809.       for (ok=0, j=0; j<l; j++) { v[j] >= '1' && v[j] <= '9' && ok++; }
  810.       if (ok != l || (ok != 2 && ok != 4)) {
  811.      fprintf(stderr, "gnuplot: illegal dashes value %s:%s\n", option, v);
  812.      dashes[n][0] = (unsigned char)0;
  813.      continue;
  814.      }
  815.       for(j=0; j<l; j++) {
  816.      dashes[n][j] = (unsigned char) (v[j] - '0');
  817.      }
  818.       dashes[n][l] = (unsigned char)0;
  819.       }
  820.    }
  821.  
  822. /*-----------------------------------------------------------------------------
  823.  *   pr_font - determine font          
  824.  *---------------------------------------------------------------------------*/
  825.  
  826. pr_font() {
  827.    char *fontname = pr_GetR(db, ".font");
  828.  
  829.    if (!fontname) fontname = FallbackFont;
  830.    font = XLoadQueryFont(dpy, fontname);
  831.    if (!font) {
  832.       fprintf(stderr, "\ngnuplot: can't load font '%s'\n", fontname);
  833.       fprintf(stderr, "gnuplot: using font '%s' instead.\n", FallbackFont);
  834.       font = XLoadQueryFont(dpy, FallbackFont);
  835.       if (!font) {
  836.      fprintf(stderr, "gnuplot: can't load font '%s'\n", FallbackFont);
  837.      fprintf(stderr, "gnuplot: no useable font - X11 aborted.\n");
  838.          exit(1);
  839.      }
  840.       }
  841.    vchar = font->ascent + font->descent;
  842.    }
  843.  
  844. /*-----------------------------------------------------------------------------
  845.  *   pr_geometry - determine window geometry      
  846.  *---------------------------------------------------------------------------*/
  847.  
  848. pr_geometry() {
  849.    char *geometry = pr_GetR(db, ".geometry");
  850.    int x, y, flags;
  851.    unsigned int w, h; 
  852.  
  853.    if (geometry) {
  854.       flags = XParseGeometry(geometry, &x, &y, &w, &h);
  855.       if (flags & WidthValue)  User_Size = 1, W = w;
  856.       if (flags & HeightValue) User_Size = 1, H = h;
  857.       if (flags & XValue) {
  858.          if (flags & XNegative)
  859.             x += DisplayWidth(dpy,scr) - W - BorderWidth*2;
  860.          User_Position = 1, gX = x;
  861.          }
  862.       if (flags & YValue) {
  863.          if (flags & YNegative)
  864.             y += DisplayHeight(dpy,scr) - H - BorderWidth*2;
  865.          User_Position = 1, gY = y;
  866.          }
  867.       }
  868.    }
  869.  
  870. /*-----------------------------------------------------------------------------
  871.  *   pr_pointsize - determine size of points for 'points' plotting style
  872.  *---------------------------------------------------------------------------*/
  873.  
  874. pr_pointsize() {
  875.    char *p = pr_GetR(db, ".pointsize") ? value.addr : "1.0" ;
  876.  
  877.    if (sscanf(p,"%lf", &pointsize) == 1) {
  878.       if (pointsize <= 0 || pointsize > 10) {
  879.      fprintf(stderr, "\ngnuplot: invalid pointsize '%s'\n", p);
  880.      pointsize = 1;
  881.      }
  882.       }
  883.    else { 
  884.       fprintf(stderr, "\ngnuplot: invalid pointsize '%s'\n", p);
  885.       pointsize = 1;
  886.       }
  887.    }
  888.  
  889. /*-----------------------------------------------------------------------------
  890.  *   pr_width - determine line width values
  891.  *---------------------------------------------------------------------------*/
  892.  
  893. char width_keys[Nwidths][30] =   { 
  894.    "border", "axis",
  895.    "line1", "line2", "line3",  "line4", "line5", "line6", "line7",  "line8" 
  896.    };
  897.  
  898. pr_width() {
  899.    int n;
  900.    char option[20], *v; 
  901.    for (n=0; n<Nwidths; n++) {
  902.       strcpy(option, ".");
  903.       strcat(option, width_keys[n]);
  904.       strcat(option, "Width");
  905.       if (v = pr_GetR(db, option)) {
  906.      if ( *v < '0' || *v > '4' || strlen(v) > 1)
  907.         fprintf(stderr, "gnuplot: illegal width value %s:%s\n", option, v);
  908.      else 
  909.         widths[n] = (unsigned int)atoi(v);
  910.      }
  911.       }
  912.    }
  913.  
  914. /*-----------------------------------------------------------------------------
  915.  *   pr_window - create window 
  916.  *---------------------------------------------------------------------------*/
  917.  
  918. pr_window() {
  919.    char *title =  pr_GetR(db, ".title");
  920.    static XSizeHints hints;
  921.    int Tvtwm = 0;
  922.  
  923.    win = XCreateSimpleWindow(dpy, root, gX, gY, W, H, BorderWidth,
  924.                              colors[1], colors[0]);
  925.  
  926.    pr_GetR(db, ".clear") && On(value.addr) && Clear++;
  927.    pr_GetR(db, ".tvtwm") && On(value.addr) && Tvtwm++;
  928.  
  929.    if (!Tvtwm) {
  930.       hints.flags = (User_Position ? USPosition : PPosition);
  931.       hints.flags |= (User_Size ? USSize : PSize);
  932.       }
  933.    else {
  934.       hints.flags = PPosition;
  935.       }
  936.    hints.x = gX; hints.y = gY;        
  937.    hints.width = W; hints.height = H;
  938.  
  939.    XSetNormalHints(dpy, win, &hints);
  940.  
  941.    if (pr_GetR(db, ".iconic") && On(value.addr)) {
  942.       XWMHints wmh;
  943.  
  944.       wmh.flags = StateHint ;
  945.       wmh.initial_state = IconicState;
  946.       XSetWMHints(dpy, win, &wmh);
  947.       } 
  948.  
  949.    XStoreName(dpy, win, ((title) ? title : Class));
  950.  
  951.    XSelectInput(dpy, win, StructureNotifyMask);
  952.    XMapWindow(dpy, win);
  953.    
  954.    }
  955.